import express from 'express';
import multer from 'multer';
import cors from 'cors';
import { recognizeQRCode } from './qrcode-recognizer.js';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import https from 'https';
import http from 'http';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 配置文件上传
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = path.join(__dirname, '../uploads');
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
  }
});

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 10 * 1024 * 1024 // 限制 10MB
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = /jpeg|jpg|png|gif|bmp|webp/;
    const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
    const mimetype = allowedTypes.test(file.mimetype);

    if (mimetype && extname) {
      return cb(null, true);
    } else {
      cb(new Error('只支持图片文件格式!'));
    }
  }
});

// 从 URL 下载图片的辅助函数
function downloadImage(url) {
  return new Promise((resolve, reject) => {
    const protocol = url.startsWith('https') ? https : http;
    const tempPath = path.join(__dirname, '../uploads', `url-${Date.now()}.jpg`);
    const uploadDir = path.join(__dirname, '../uploads');

    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }

    const file = fs.createWriteStream(tempPath);

    protocol.get(url, (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(`下载失败，HTTP 状态码: ${response.statusCode}`));
        return;
      }

      response.pipe(file);

      file.on('finish', () => {
        file.close();
        resolve(tempPath);
      });
    }).on('error', (err) => {
      fs.unlink(tempPath, () => {});
      reject(new Error(`下载图片失败: ${err.message}`));
    });

    file.on('error', (err) => {
      fs.unlink(tempPath, () => {});
      reject(new Error(`保存图片失败: ${err.message}`));
    });
  });
}

// 根路由
app.get('/', (req, res) => {
  res.json({
    message: '二维码识别 API',
    version: '2.0.0',
    endpoints: {
      'POST /api/recognize': '识别二维码（支持文件上传、URL、Base64）',
      'POST /api/recognize-base64': '通过 Base64 识别二维码（已整合到 /api/recognize）',
      'GET /health': '健康检查'
    },
    usage: {
      method1: {
        name: '文件上传',
        contentType: 'multipart/form-data',
        params: { image: 'File' }
      },
      method2: {
        name: 'URL 地址',
        contentType: 'application/json 或 multipart/form-data',
        params: { url: 'http://example.com/image.jpg' }
      },
      method3: {
        name: 'Base64',
        contentType: 'application/json',
        params: { image: 'data:image/png;base64,...' }
      }
    }
  });
});

// 健康检查
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

// 上传图片识别二维码（支持文件上传和 URL）
app.post('/api/recognize', upload.single('image'), async (req, res) => {
  let imagePath = null;
  let isTemporaryFile = false;

  try {
    // 方式1: 通过 URL 识别
    if (req.body.url) {
      const imageUrl = req.body.url;
      console.log('通过 URL 识别:', imageUrl);

      // 下载图片
      imagePath = await downloadImage(imageUrl);
      isTemporaryFile = true;
    }
    // 方式2: 通过文件上传识别
    else if (req.file) {
      imagePath = req.file.path;
      isTemporaryFile = true;
    }
    // 方式3: 通过 Base64 识别（兼容）
    else if (req.body.image) {
      const base64Data = req.body.image.replace(/^data:image\/\w+;base64,/, '');
      const buffer = Buffer.from(base64Data, 'base64');

      imagePath = path.join(__dirname, '../uploads', `base64-${Date.now()}.png`);
      const uploadDir = path.join(__dirname, '../uploads');
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true });
      }
      fs.writeFileSync(imagePath, buffer);
      isTemporaryFile = true;
    }
    else {
      return res.status(400).json({
        success: false,
        error: '请提供图片文件、URL 地址或 Base64 数据',
        usage: {
          method1: '文件上传: form-data 中 image 字段上传文件',
          method2: 'URL 地址: form-data 或 JSON 中 url 字段传入图片 URL',
          method3: 'Base64: JSON 中 image 字段传入 Base64 数据'
        }
      });
    }

    // 识别二维码
    const result = await recognizeQRCode(imagePath);

    // 删除临时文件
    if (isTemporaryFile && fs.existsSync(imagePath)) {
      fs.unlinkSync(imagePath);
    }

    if (result.success) {
      res.json({
        success: true,
        data: result.data,
        count: result.count,
        message: `成功识别 ${result.count} 个二维码`
      });
    } else {
      res.json({
        success: false,
        error: result.error || '未识别到二维码'
      });
    }
  } catch (error) {
    console.error('识别错误:', error);

    // 清理临时文件
    if (isTemporaryFile && imagePath && fs.existsSync(imagePath)) {
      fs.unlinkSync(imagePath);
    }

    res.status(500).json({
      success: false,
      error: error.message || '服务器内部错误'
    });
  }
});

// Base64 图片识别
app.post('/api/recognize-base64', async (req, res) => {
  try {
    const { image } = req.body;

    if (!image) {
      return res.status(400).json({
        success: false,
        error: '请提供 base64 编码的图片'
      });
    }

    // 移除 data:image/xxx;base64, 前缀
    const base64Data = image.replace(/^data:image\/\w+;base64,/, '');
    const buffer = Buffer.from(base64Data, 'base64');

    // 保存临时文件
    const tempPath = path.join(__dirname, '../uploads', `temp-${Date.now()}.png`);
    const uploadDir = path.join(__dirname, '../uploads');
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }
    fs.writeFileSync(tempPath, buffer);

    // 识别二维码
    const result = await recognizeQRCode(tempPath);

    // 删除临时文件
    fs.unlinkSync(tempPath);

    if (result.success) {
      res.json({
        success: true,
        data: result.data,
        count: result.count,
        message: `成功识别 ${result.count} 个二维码`
      });
    } else {
      res.json({
        success: false,
        error: result.error || '未识别到二维码'
      });
    }
  } catch (error) {
    console.error('识别错误:', error);
    res.status(500).json({
      success: false,
      error: error.message || '服务器内部错误'
    });
  }
});

// 错误处理中间件
app.use((error, req, res, next) => {
  console.error('错误:', error);
  res.status(error.status || 500).json({
    success: false,
    error: error.message || '服务器内部错误'
  });
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`🚀 二维码识别 API 服务已启动`);
  console.log(`📡 监听端口: ${PORT}`);
  console.log(`🌐 访问地址: http://localhost:${PORT}`);
  console.log(`\n可用的 API 端点:`);
  console.log(`  POST http://localhost:${PORT}/api/recognize - 识别二维码`);
  console.log(`    支持方式: 文件上传 | URL 地址 | Base64`);
  console.log(`  POST http://localhost:${PORT}/api/recognize-base64 - Base64 识别（已整合）`);
  console.log(`  GET  http://localhost:${PORT}/health - 健康检查`);
  console.log(`\n使用示例:`);
  console.log(`  方式1 - 文件上传: curl -F "image=@qrcode.png" http://localhost:${PORT}/api/recognize`);
  console.log(`  方式2 - URL 地址: curl -X POST -H "Content-Type: application/json" -d '{"url":"http://example.com/qr.jpg"}' http://localhost:${PORT}/api/recognize`);
  console.log(`  方式3 - Base64: curl -X POST -H "Content-Type: application/json" -d '{"image":"data:image/png;base64,..."}' http://localhost:${PORT}/api/recognize\n`);
});

export default app;

